#include "orderdao.h"
#include <QDate>
#include <QDebug>

OrderDAO::OrderDAO(Database *db) : m_db(db) {}

int OrderDAO::createOrder(const Order &order)
{
    if (!m_db->isConnected()) {
        qWarning() << "数据库未连接";
        return -1;
    }

    // 开始事务
    if (!m_db->beginTransaction()) {
        qWarning() << "开始事务失败";
        return -1;
    }

    try {
        // 插入订单主表
            QString query = "INSERT INTO order_main (user_id, customer_id, order_time, "
                           "total_amount, discount_amount, final_amount, method_id, "
                           "order_status) "  // 移除了transaction_no和payment_time
                           "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";  // 参数减少到8个

        QMap<QString, QVariant> orderData = order.toDatabaseFormat();
        QVector<QVariant> params = {
            orderData["user_id"],
                    orderData["customer_id"],
                    orderData["order_time"],
                    orderData["total_amount"],
                    orderData["discount_amount"],
                    orderData["final_amount"],
                    orderData["method_id"],
                    orderData["order_status"]  // 新订单状态应为ORDER_PENDING(0)
        };

        if (!m_db->execute(query, params)) {
            throw QString("插入订单失败");
        }

        // 获取刚插入的订单ID
        QString lastIdQuery = "SELECT LAST_INSERT_ID() as order_id";
        QVector<QMap<QString, QVariant>> result = m_db->query(lastIdQuery);

        if (result.isEmpty()) {
            throw QString("获取订单ID失败");
        }

        int orderId = result.first()["order_id"].toInt();

        // 插入订单详情
        QVector<OrderDetail> details = order.getOrderDetails();
        for (const OrderDetail &detail : details) {
            QString detailQuery = "INSERT INTO order_detail (order_id, product_id, "
                                "quantity, unit_price, subtotal, is_discounted) "
                                "VALUES (?, ?, ?, ?, ?, ?)";

            QVector<QVariant> detailParams = {
                orderId,
                detail.productId,
                detail.quantity,
                detail.unitPrice,
                detail.subtotal,
                detail.isDiscounted ? 1 : 0
            };

            if (!m_db->execute(detailQuery, detailParams)) {
                throw QString("插入订单详情失败");
            }
        }

        // 提交事务
        if (!m_db->commitTransaction()) {
            throw QString("提交事务失败");
        }

        return orderId;
    } catch (const QString &error) {
        // 回滚事务
        m_db->rollbackTransaction();
        qWarning() << error;
        return -1;
    }
}

Order OrderDAO::getOrderById(int orderId)
{
    QString query = "SELECT * FROM order_main WHERE order_id = ?";
    QVector<QMap<QString, QVariant>> result = m_db->query(query, {orderId});

    if (result.isEmpty()) {
        return Order();
    }

    Order order = Order::fromDatabaseResult(result.first());

    // 加载订单详情
    QVector<OrderDetail> details = getOrderDetails(orderId);
    for (const OrderDetail &detail : details) {
        order.addOrderDetail(detail.productId, detail.quantity,
                            detail.unitPrice, detail.subtotal,
                            detail.isDiscounted);
    }

    return order;
}

QVector<Order> OrderDAO::getAllOrders()
{
    QString query = "SELECT * FROM order_main ORDER BY order_time DESC";
    QVector<QMap<QString, QVariant>> results = m_db->query(query);

    QVector<Order> orders;
    for (const auto &result : results) {
        Order order = Order::fromDatabaseResult(result);

        // 加载订单详情
        QVector<OrderDetail> details = getOrderDetails(order.getOrderId());
        for (const OrderDetail &detail : details) {
            order.addOrderDetail(detail.productId, detail.quantity,
                                detail.unitPrice, detail.subtotal,
                                detail.isDiscounted);
        }

        orders.append(order);
    }

    return orders;
}

QVector<Order> OrderDAO::getOrdersByUserId(int userId)
{
    QString query = "SELECT * FROM order_main WHERE user_id = ? ORDER BY order_time DESC";
    QVector<QMap<QString, QVariant>> results = m_db->query(query, {userId});

    QVector<Order> orders;
    for (const auto &result : results) {
        Order order = Order::fromDatabaseResult(result);

        // 加载订单详情
        QVector<OrderDetail> details = getOrderDetails(order.getOrderId());
        for (const OrderDetail &detail : details) {
            order.addOrderDetail(detail.productId, detail.quantity,
                                detail.unitPrice, detail.subtotal,
                                detail.isDiscounted);
        }

        orders.append(order);
    }

    return orders;
}

QVector<Order> OrderDAO::getOrdersByCustomerId(int customerId)
{
    QString query = "SELECT * FROM order_main WHERE customer_id = ? ORDER BY order_time DESC";
    QVector<QMap<QString, QVariant>> results = m_db->query(query, {customerId});

    QVector<Order> orders;
    for (const auto &result : results) {
        Order order = Order::fromDatabaseResult(result);

        // 加载订单详情
        QVector<OrderDetail> details = getOrderDetails(order.getOrderId());
        for (const OrderDetail &detail : details) {
            order.addOrderDetail(detail.productId, detail.quantity,
                                detail.unitPrice, detail.subtotal,
                                detail.isDiscounted);
        }

        orders.append(order);
    }

    return orders;
}

QVector<Order> OrderDAO::getOrdersByDateRange(const QDateTime &startDate, const QDateTime &endDate)
{
    QString query = "SELECT * FROM order_main WHERE order_time BETWEEN ? AND ? ORDER BY order_time DESC";
    QVector<QVariant> params = {startDate, endDate};

    QVector<QMap<QString, QVariant>> results = m_db->query(query, params);

    QVector<Order> orders;
    for (const auto &result : results) {
        Order order = Order::fromDatabaseResult(result);

        // 加载订单详情
        QVector<OrderDetail> details = getOrderDetails(order.getOrderId());
        for (const OrderDetail &detail : details) {
            order.addOrderDetail(detail.productId, detail.quantity,
                                detail.unitPrice, detail.subtotal,
                                detail.isDiscounted);
        }

        orders.append(order);
    }

    return orders;
}

bool OrderDAO::updateOrderStatus(int orderId, OrderStatus status)
{
    QString query = "UPDATE order_main SET order_status = ? WHERE order_id = ?";
    QVector<QVariant> params = {static_cast<int>(status), orderId};

    return m_db->execute(query, params);
}

bool OrderDAO::updateOrderPayment(int orderId, const QString &transactionNo, const QDateTime &paymentTime)
{
    QString query = "UPDATE order_main SET transaction_no = ?, payment_time = ?, order_status = ? WHERE order_id = ?";
    QVector<QVariant> params = {transactionNo, paymentTime, static_cast<int>(ORDER_PAID), orderId};

    return m_db->execute(query, params);
}

bool OrderDAO::deleteOrder(int orderId)
{
    if (!m_db->isConnected()) {
        qWarning() << "数据库未连接";
        return false;
    }

    // 开始事务
    if (!m_db->beginTransaction()) {
        qWarning() << "开始事务失败";
        return false;
    }

    try {
        // 先删除订单详情
        if (!deleteOrderDetails(orderId)) {
            throw QString("删除订单详情失败");
        }

        // 再删除订单主表
        QString query = "DELETE FROM order_main WHERE order_id = ?";
        if (!m_db->execute(query, {orderId})) {
            throw QString("删除订单失败");
        }

        // 提交事务
        if (!m_db->commitTransaction()) {
            throw QString("提交事务失败");
        }

        return true;
    } catch (const QString &error) {
        // 回滚事务
        m_db->rollbackTransaction();
        qWarning() << error;
        return false;
    }
}

QVector<OrderDetail> OrderDAO::getOrderDetails(int orderId)
{
    QString query = "SELECT * FROM order_detail WHERE order_id = ?";
    QVector<QMap<QString, QVariant>> results = m_db->query(query, {orderId});

    QVector<OrderDetail> details;
    for (const auto &result : results) {
        OrderDetail detail;
        detail.orderId = result["order_id"].toInt();
        detail.productId = result["product_id"].toInt();
        detail.quantity = result["quantity"].toInt();
        detail.unitPrice = result["unit_price"].toDouble();
        detail.subtotal = result["subtotal"].toDouble();
        detail.isDiscounted = result["is_discounted"].toBool();

        details.append(detail);
    }

    return details;
}

bool OrderDAO::addOrderDetail(const OrderDetail &detail)
{
    QString query = "INSERT INTO order_detail (order_id, product_id, quantity, unit_price, subtotal, is_discounted) "
                   "VALUES (?, ?, ?, ?, ?, ?)";

    QVector<QVariant> params = {
        detail.orderId,
        detail.productId,
        detail.quantity,
        detail.unitPrice,
        detail.subtotal,
        detail.isDiscounted ? 1 : 0
    };

    return m_db->execute(query, params);
}

bool OrderDAO::deleteOrderDetails(int orderId)
{
    QString query = "DELETE FROM order_detail WHERE order_id = ?";
    return m_db->execute(query, {orderId});
}

int OrderDAO::getTodayOrderCount()
{
    QDateTime todayStart = QDateTime::currentDateTime();
    todayStart.setTime(QTime(0, 0, 0));

    QDateTime todayEnd = QDateTime::currentDateTime();
    todayEnd.setTime(QTime(23, 59, 59));

    QString query = "SELECT COUNT(*) as count FROM order_main WHERE order_time BETWEEN ? AND ?";
    QVector<QVariant> params = {todayStart, todayEnd};

    QVector<QMap<QString, QVariant>> result = m_db->query(query, params);

    if (result.isEmpty()) {
        return 0;
    }

    return result.first()["count"].toInt();
}

double OrderDAO::getTodaySales()
{
    QDateTime todayStart = QDateTime::currentDateTime();
    todayStart.setTime(QTime(0, 0, 0));

    QDateTime todayEnd = QDateTime::currentDateTime();
    todayEnd.setTime(QTime(23, 59, 59));

    QString query = "SELECT SUM(final_amount) as total FROM order_main WHERE order_time BETWEEN ? AND ? AND order_status = 1";
    QVector<QVariant> params = {todayStart, todayEnd};

    QVector<QMap<QString, QVariant>> result = m_db->query(query, params);

    if (result.isEmpty() || result.first()["total"].isNull()) {
        return 0.0;
    }

    return result.first()["total"].toDouble();
}

QMap<QString, double> OrderDAO::getSalesStatistics(const QDateTime &startDate, const QDateTime &endDate)
{
    QMap<QString, double> statistics;

    // 总销售额
    QString totalSalesQuery = "SELECT SUM(final_amount) as total FROM order_main "
                             "WHERE order_time BETWEEN ? AND ? AND order_status IN (1, 2)";
    QVector<QVariant> params = {startDate, endDate};

    QVector<QMap<QString, QVariant>> totalResult = m_db->query(totalSalesQuery, params);
    if (!totalResult.isEmpty() && !totalResult.first()["total"].isNull()) {
        statistics["total_sales"] = totalResult.first()["total"].toDouble();
    } else {
        statistics["total_sales"] = 0.0;
    }

    // 订单数量
    QString orderCountQuery = "SELECT COUNT(*) as count FROM order_main "
                             "WHERE order_time BETWEEN ? AND ? AND order_status IN (1, 2)";
    QVector<QMap<QString, QVariant>> countResult = m_db->query(orderCountQuery, params);
    if (!countResult.isEmpty()) {
        statistics["order_count"] = countResult.first()["count"].toDouble();
    } else {
        statistics["order_count"] = 0.0;
    }

    // 平均订单金额
    if (statistics["order_count"] > 0) {
        statistics["average_order"] = statistics["total_sales"] / statistics["order_count"];
    } else {
        statistics["average_order"] = 0.0;
    }

    // 按支付方式统计
    QString paymentMethodQuery = "SELECT method_id, SUM(final_amount) as total FROM order_main "
                                "WHERE order_time BETWEEN ? AND ? AND order_status IN (1, 2) "
                                "GROUP BY method_id";
    QVector<QMap<QString, QVariant>> methodResult = m_db->query(paymentMethodQuery, params);
    for (const auto &row : methodResult) {
        int methodId = row["method_id"].toInt();
        double total = row["total"].toDouble();
        statistics[QString("method_%1").arg(methodId)] = total;
    }

    return statistics;
}
